﻿#include <iostream>
#include <string>
using namespace std;

//class Person
//{
//public:
//	void Print()
//	{
//		cout << "name:" << _name << endl;
//		cout << "age:" << _age << endl;
//	}
//protected:
//	string _name = "zhangsan";
//	int _age = 18;
//};
//
//// 继承后父类的Person的成员（成员函数+成员变量）都会变成子类的一部分。这里体现出了
//// Student和Teacher复用了Person的成员。下面我们使用监视窗口查看Student和Teacher对象，可
//// 以看到变量的复用。调用Print可以看到成员函数的复用。
//class Student : public Person
//{
//protected:
//	int _stuid;
//};
//
//class Teacher : public Person
//{
//protected:
//	int _teaid;
//};
//
//int main()
//{
//	Student stu;
//	Teacher tea;
//	stu.Print();
//	tea.Print();
//	return 0;
//}
//
//class Person
//{
//protected:
//	string _name;
//	int _age;
//	string _sex;
//};
//
//class Student : public Person
//{
//public:
//	int _stuid;
//};
//
//int main()
//{
//	Student stu;
//
//	Person per = stu;
//	Person* pper = &stu;
//	Person& rper = stu;
//
//	// 基类对象不能赋值给派生类对象
//	// stu = per; 
//
//	// 基类的指针可以通过强制类型转换赋值给派生类指针
//	Student* pstu = (Student*)pper;
//	pstu->_stuid = 3;
//
//	pper = &per;
//	Student* ps = (Student*)pper; // 这种情况虽然可以，但会存在越界访问的问题
//	ps->_stuid = 6;
//	return 0;
//}

// Student的_num和Person的_num构成隐藏关系，可以看出这样代码虽然能跑，但是非常容易混淆
//class Person
//{
//protected:
//	string _name = "zhangsan"; // 姓名
//	int _num = 333;   // 身份证号
//};
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout << " 姓名:" << _name << endl;
//		// 这里想要访问基类的同名成员，只能显示访问
//		cout << " 身份证号:" << Person::_num << endl;
//		cout << " 学号:" << _num << endl;
//	}
//protected:
//	int _num = 666; // 学号
//};
//int main()
//{
//	Student stu;
//	stu.Print();
//};

// Person中的Print()和Student中的Print(int i)不构成重载，因为不在同一个作用域
// Person中的Print()和Student中的Print(int i)构成隐藏，成员函数满足成员函数名相同就构成隐藏
//class Person
//{
//public:
//	void Print() {
//		cout << "Print()" << endl;
//	}
//};
//
//class Student
//{
//public:
//	void Print(int i) {
//		cout << "Print(int i)" << endl;
//	}
//};
//
//int main()
//{
//	Student stu;
//	stu.Print(3);
//}

//class Person
//{
//public:
//	Person(string name, int age)
//		:_name(name), _age(age)
//	{
//		cout << "Person(string name, int age)" << endl;
//	}
//
//	Person(const Person& per)
//	{
//		_name = per._name;
//		_age = per._age;
//		cout << "Person(const Person& per)" << endl;
//	}
//
//	Person& operator=(const Person& per)
//	{
//		_name = per._name;
//		_age = per._age;
//		cout << "Person& operator=(const Person& per)" << endl;
//
//		return *this;
//	}
//
//	~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//
//protected:
//	string _name;
//	int _age;
//};
//
//class Student : public Person
//{
//public:
//	Student(string name, int age, int id)
//		:Person(name, age),
//		_id(id)
//	{
//		cout << "Student(string name, int age, int id)" << endl;
//	}
//
//	Student(const Student& stu)
//		:Person(stu),
//		_id(stu._id)
//	{
//		cout << "Student(const Student& stu)" << endl;
//	}
//
//	Student& operator=(const Student& stu)
//	{
//		Person::operator=(stu);
//		_id = stu._id;
//		cout << "Student& operator=(const Student& stu)" << endl;
//
//		return *this;
//	}
//
//	~Student()
//	{
//		cout << "~Student()" << endl;
//	}
//private:
//	int _id;
//};
//
//int main()
//{
//	Student s1("zhangsan", 18, 333); // 构造函数
//	Student s2(s1); // 拷贝构造函数
//	Student s3("lisi", 21, 666);
//	s3 = s1; // 赋值重载
//
//	return 0;
//}

//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名
//};
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl;
//}
//void main()
//{
//	Person p;
//	Student s;
//	Display(p, s);
//}

//class Person
//{
//public:
//	string _name;
//};
//
//class Student : virtual public Person
//{
//protected: 
//	int _stuid;   // 学号
//};
//
//class Teacher : virtual public Person
//{
//protected:
//	int _teaid;
//};
//
//class Graduate : public Student, public Teacher
//{
//private:
//	string _course; // 课程
//};
//
//
//int main()
//{
//	Graduate g;
//	g._name = "aaa"; // 此时就不会报错
//	return 0;
//}

class A
{
public:
	int _a;
};
// class B : public A
class B : virtual public A
{
public:
	int _b;
};
// class C : public A
class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};
int main()
{
	D d;
	B b = d;
	C c = d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;

	return 0;
}


// Car和BMW Car和Benz构成is-a的关系
class Car {
protected:
	string _colour = "白色"; // 颜色
	string _num = "陕ABIT00"; // 车牌号
};

class BMW : public Car {
public:
	void Drive() { cout << "好开-操控" << endl; }
};

class Benz : public Car {
public:
	void Drive() { cout << "好坐-舒适" << endl; }
};

// Tire和Car构成has-a的关系

class Tire {
protected:
	string _brand = "Michelin";  // 品牌
	size_t _size = 17;         // 尺寸

};

class Car {
protected:
	string _colour = "白色"; // 颜色
	string _num = "陕ABIT00"; // 车牌号
	Tire _t; // 轮胎
};